/* --COPYRIGHT--
 * Copyright (c) 2013, Tyro EV
 * All rights reserved.
 * --/COPYRIGHT--*/

#include "inc/hw_memmap.h"
//#include "usci_i2c.h"
//#include "wdt_a.h"
#include "gpio.h"
#include "adc12_a.h"
#include "wdt_a.h"
#include "LED.h"
#include "I2C_IO_Driver.h"
//#include "frame.h"
#include "SI.h"
#include "SI_NS.h"
#include "SOSZ.h"
#include "Relay.h"
#include "Button.h"
#include "SIadc.h"
#include "Fault.h"
#include "GA.h"
#include "FWS.h"
//#include "LED.h"
//#include "DataType.h".h
#include "h1010.h"
#include "main.h"

/*enum SI_STATE {  DO NOT CHANGE ORDER OF STATES!!!
	SI_STATE_IDLE,
	SI_STATE_alarmEntryTimer,
	SI_STATE_alarmEntryTimerFWS_waitForAck,
	SI_STATE_alarmEntryTimerFWS_Acked,
	SI_STATE_alarmWaitForAck,
	SI_STATE_alarmWaitForResetOrFltClear,
	SI_STATE_alarmWaitForAck_afterResetOrFltClear,
	SI_STATE_faultWaitForAck,
	SI_STATE_faultWaitForFltClear,
	SI_STATE_faultWaitForAck_afterFltClear
};*/
/*enum SI_X {
	SI_1=0,
	SI_2=1,
	SI_3=2,
	SI_4=3,
	SI_5=4,
	SI_6=5,
	SI_7=6,
	SI_8=7,
	SI_9=8,
	SI_10=9,
	SI_11=10,
	SI_12=11
};
enum SI_X_mask {
	SI_1m=0x01,
	SI_2m=0x02,
	SI_3m=0x04,
	SI_4m=0x08,
	SI_5m=0x10,
	SI_6m=0x20,
	SI_7m=0x40,
	SI_8m=0x80
};*/

#define TICKS_FROM_25ms
#ifdef TICKS_FROM_75ms
	#define TICKS_LED_FOR_150ms 	2
	#define TICKS_SOSZ_FOR_1sec 	13
	#define TICKS_BTN_FOR_150ms 	2
	#define TICKS_ADC_FOR_150ms 	2
	#define TICKS_ADC_FOR_75ms 		1
	#define TICKS_LOCKOUT_FOR_3sec 	39
#endif
#ifdef TICKS_FROM_25ms
	#define TICKS_LED_FOR_150ms 	(2*3)
	#define TICKS_SOSZ_FOR_1sec 	(13*3)
	#define TICKS_BTN_FOR_150ms 	(2*3)
	#define TICKS_BTN_FOR_25ms 		(1)
	#define TICKS_ADC_FOR_3sec 	    (39*3)
	#define TICKS_ADC_FOR_900ms 	(12*3)
	#define TICKS_ADC_FOR_600ms 	(8*3)
	#define TICKS_ADC_FOR_450ms 	(6*3)
	#define TICKS_ADC_FOR_375ms 	(5*3)
	#define TICKS_ADC_FOR_300ms 	(4*3)
	#define TICKS_ADC_FOR_225ms 	(3*3)
	#define TICKS_ADC_FOR_150ms 	(2*3)
	#define TICKS_ADC_FOR_75ms 		(1*3)
	#define TICKS_LOCKOUT_FOR_3sec 	(39*3)
#endif
	#define TICKS_LOCKOUT_FOR_3sec_FROM_1sec 3
struct SI_adcInfo {
	unsigned int currentAdc;
	unsigned int lastAdc;
	unsigned int filteredAdc;
};
/*struct SI_threadInfo_t {
	enum SI_ADC_STATE adcState;
	enum SI_ADC_STATE adcStateTarget;
	unsigned char adcFilterCount; // for simple adc filter, count to SI_ADC_FILTER_COUNT before transition
	enum SI_STATE alarmState;
	enum SI_STATE faultState;
	enum LED_INDEX alarmLed;
	enum LED_INDEX faultLed;
	enum LED_INDEX globalAlarmLed;
	enum LED_INDEX globalFaultLed;
	unsigned char buzzerValid;
	unsigned int adcCount;
	unsigned int oneSecTickCount;
	struct SI * pSI;
};*/
struct SI_threadInfo_t SI_threadInfo[SI_ACTIVE] =
	{{SI_ADC_NORMAL, SI_ADC_NORMAL, 0, SI_STATE_IDLE, SI_STATE_IDLE, LED_Begin, LED_Begin, LED_Begin, LED_Begin, 0, 0, 0, 0, 0, 0},
	 {SI_ADC_NORMAL, SI_ADC_NORMAL, 0, SI_STATE_IDLE, SI_STATE_IDLE, LED_Begin, LED_Begin, LED_Begin, LED_Begin, 0, 0, 0, 0, 0, 0},
	 {SI_ADC_NORMAL, SI_ADC_NORMAL, 0, SI_STATE_IDLE, SI_STATE_IDLE, LED_Begin, LED_Begin, LED_Begin, LED_Begin, 0, 0, 0, 0, 0, 0},
	 {SI_ADC_NORMAL, SI_ADC_NORMAL, 0, SI_STATE_IDLE, SI_STATE_IDLE, LED_Begin, LED_Begin, LED_Begin, LED_Begin, 0, 0, 0, 0, 0, 0},
	 {SI_ADC_NORMAL, SI_ADC_NORMAL, 0, SI_STATE_IDLE, SI_STATE_IDLE, LED_Begin, LED_Begin, LED_Begin, LED_Begin, 0, 0, 0, 0, 0, 0},
	 {SI_ADC_NORMAL, SI_ADC_NORMAL, 0, SI_STATE_IDLE, SI_STATE_IDLE, LED_Begin, LED_Begin, LED_Begin, LED_Begin, 0, 0, 0, 0, 0, 0},
 	 {SI_ADC_NORMAL, SI_ADC_NORMAL, 0, SI_STATE_IDLE, SI_STATE_IDLE, LED_Begin, LED_Begin, LED_Begin, LED_Begin, 0, 0, 0, 0, 0, 0},
	 {SI_ADC_NORMAL, SI_ADC_NORMAL, 0, SI_STATE_IDLE, SI_STATE_IDLE, LED_Begin, LED_Begin, LED_Begin, LED_Begin, 0, 0, 0, 0, 0, 0},
	};
struct SI_threadInfo_t * SI_rtnThreadInfo(enum SI_X siMe)
{
	struct SI_threadInfo_t * ptrThreadInfo = (struct SI_threadInfo_t *)&SI_threadInfo[siMe];
	return ptrThreadInfo;
}
enum SI_ADC_STATE SI_getAdcState(enum SI_X siMe)
{
	return SI_threadInfo[siMe].adcState;
}

/* Call Led every other 75ms */
#define TICKS_LED 		TICKS_LED_FOR_150ms
static unsigned char 	ticksLed = TICKS_LED*3+1;
/* Call SOSZ once per second */
#define TICKS_SOSZ 		TICKS_SOSZ_FOR_1sec
static unsigned int 	ticksSOSZ = TICKS_SOSZ*3+2;
/* Call button every other 75ms */
#define TICKS_BTN 		TICKS_BTN_FOR_25ms
static unsigned char 	ticksBtn = TICKS_BTN;
/* Call button every 75ms */
#define TICKS_ADC 		TICKS_ADC_FOR_300ms//TICKS_ADC_FOR_600ms//TICKS_ADC_FOR_75ms
static unsigned char 	ticksADC = TICKS_ADC*3+3;
/* Lockout timer for LAMP_TEST, 3 seconds */
#define TICKS_LOCKOUT 	TICKS_LOCKOUT_FOR_3sec_FROM_1sec
static unsigned int 	lockOutTimer = TICKS_LOCKOUT;
#define TICKS_FAULT		TICKS_SOSZ_FOR_1sec
static unsigned int 	ticksFault = TICKS_FAULT*4;


static enum e_mode mode = MODE_NORMAL;//MODE_LAMP_TEST;//MODE_NORMAL;

#define SI_TEST_AD_PORT	GPIO_PORT_P10
#define SI_TEST_AD_PIN	GPIO_PIN6

#define SI_24_OUT_ENABLE_PORT 	GPIO_PORT_P7
#define SI_24_OUT_ENABLE_PIN	GPIO_PIN1

#define SI_24V_OUT_PORT		GPIO_PORT_P1
#define SI_8_24V_OUT_PIN	GPIO_PIN7		// J6-8
#define SI_7_24V_OUT_PIN	GPIO_PIN6		// J6-7
#define SI_6_24V_OUT_PIN	GPIO_PIN5		// J6-6
#define SI_5_24V_OUT_PIN	GPIO_PIN4		// J6-5
#define SI_4_24V_OUT_PIN	GPIO_PIN3		// J6-4
#define SI_3_24V_OUT_PIN	GPIO_PIN2		// J6-3
#define SI_2_24V_OUT_PIN	GPIO_PIN1		// J6-2
#define SI_1_24V_OUT_PIN	GPIO_PIN0		// J6-1
#define SI_24V_OUT_PIN_MASK	(GPIO_PIN0 | GPIO_PIN1 | GPIO_PIN2 | GPIO_PIN3 | GPIO_PIN4 | GPIO_PIN5 | GPIO_PIN6 | GPIO_PIN7)

#define TIMER_25p0msec_1p05MHz_div1		0x3392
#define TIMER_30p1msec_1p05MHz_div1		0x3E80
#define TIMER_75p0msec_1p05MHz_div1		0x9ab6
#define TIMER_100msec_1p05MHz_div1		0xCE48
#define TIMER_62p05msec_1p05MHz_div1	0x7FFF
#define TIMER_124p1msec_1p05MHz_div1	0xFFFF

#define TIMER_25p0msec_8MHz_div8		0x3392
#define TIMER_25p0msec_16MHz_div8		0x6724
#define TIMER_25p0msec_16MHz_div16		0x3392
#define TIMER_25p0msec_25MHz_div16		0x5094
#define TIMER_25p0msec_32MHz_div16		0x6724

#define TIMER_CTL_1p05MHz_div1		(TASSEL_2 + MC__UPDOWN)
#define TIMER_CTL_8MHz_div8			(TASSEL_2 + MC__UPDOWN + ID__8)
#define TIMER_CTL_16MHz_div8		(TASSEL_2 + MC__UPDOWN + ID__8)
#define TIMER_CTL_16MHz_div16		(TASSEL_2 + MC__UPDOWN + ID__8)
#define TIMER_CTL_25MHz_div16		(TASSEL_2 + MC__UPDOWN + ID__8)
#define TIMER_CTL_32MHz_div16		(TASSEL_2 + MC__UPDOWN + ID__8)

#define TIMER_TA1EX0_1p05MHz_div1	TAIDEX_0
#define TIMER_TA1EX0_8MHz_div8		TAIDEX_0
#define TIMER_TA1EX0_16MHz_div8		TAIDEX_0
#define TIMER_TA1EX0_16MHz_div16	TAIDEX_1
#define TIMER_TA1EX0_25MHz_div16	TAIDEX_1
#define TIMER_TA1EX0_32MHz_div16	TAIDEX_1

#if TIMER_1MHz_div1
#define UPDATE_STATE_TIMER		TIMER_25p0msec_1p05MHz_div1//TIMER_124p1msec
#define TIMER_CTL				TIMER_CTL_1p05MHz_div1
#define TIMER_TA1EX0			TIMER_TA1EX0_1p05MHz_div1
#elif TIMER_8MHz_div8
#define UPDATE_STATE_TIMER		TIMER_25p0msec_8MHz_div8//TIMER_124p1msec
#define TIMER_CTL				TIMER_CTL_8MHz_div8
#define TIMER_TA1EX0			TIMER_TA1EX0_8MHz_div8
#elif TIMER_16Mhz_div8
#define UPDATE_STATE_TIMER		TIMER_25p0msec_16MHz_div8//TIMER_25p0msec_1p05MHz_div1//TIMER_124p1msec
#define TIMER_CTL				TIMER_CTL_16MHz_div8
#define TIMER_TA1EX0			TIMER_TA1EX0_16MHz_div8
#elif TIMER_16Mhz_div16
#define UPDATE_STATE_TIMER		TIMER_25p0msec_16MHz_div16//TIMER_25p0msec_1p05MHz_div1//TIMER_124p1msec
#define TIMER_CTL				TIMER_CTL_16MHz_div16
#define TIMER_TA1EX0			TIMER_TA1EX0_16MHz_div16
#elif TIMER_25Mhz_div16
#define UPDATE_STATE_TIMER		TIMER_25p0msec_25MHz_div16//TIMER_25p0msec_1p05MHz_div1//TIMER_124p1msec
#define TIMER_CTL				TIMER_CTL_25MHz_div16
#define TIMER_TA1EX0			TIMER_TA1EX0_25MHz_div16
#elif TIMER_32Mhz_div16
#define UPDATE_STATE_TIMER		TIMER_25p0msec_32MHz_div16//TIMER_25p0msec_1p05MHz_div1//TIMER_124p1msec
#define TIMER_CTL				TIMER_CTL_32MHz_div16
#define TIMER_TA1EX0			TIMER_TA1EX0_32MHz_div16
#else
#define UPDATE_STATE_TIMER		TIMER_25p0msec_1p05MHz_div1//TIMER_124p1msec
#endif
static unsigned int oneSecondTick = 0;

void SI_threadInfo_init(struct SI_threadInfo_t * me, enum LED_INDEX alarm, enum LED_INDEX fault, enum LED_INDEX gblAlm);
//void SI_threadInfo_reset(struct SI_threadInfo_t * me);
//void SI_thread(void);

void SI_init (void);
//void SI_init25msTimerISR(void);
//void SI_init25msTimerISR(void);
//void SI_enable25msISR(void);
void SI_atomicTimer(void);

void SI_globalLedLogic(void);
void SI_updateBtnTimer(void);

void SI_adcToStatus_type6(unsigned int *adcCounts, enum SI_ADC_STATE * state);
void SI_adcToStatus_type4(unsigned int *adcCounts, enum SI_ADC_STATE * state);

void SI_alarmIDLE(enum LED_INDEX almLed, enum LED_INDEX globalAlarmLed);
void SI_alarmEntryTimerFWS_waitForAck(enum LED_INDEX almLed, enum LED_INDEX globalAlarmLed);
void SI_alarmWaitForAck(enum LED_INDEX almLed, enum LED_INDEX globalAlarmLed);
void SI_alarmWaitForResetOrFltClear(enum LED_INDEX almLed, enum LED_INDEX globalAlarmLed);
void SI_alarmWaitForAck_afterResetOrFltClear(enum LED_INDEX almLed, enum LED_INDEX globalAlarmLed);
void SI_faultIDLE(enum LED_INDEX fltLed, enum LED_INDEX globalFaultLed);
void SI_faultWaitForAck(enum LED_INDEX fltLed, enum LED_INDEX globalFaultLed);
void SI_faultWaitForFltClear(enum LED_INDEX fltLed, enum LED_INDEX globalFaultLed);
void SI_faultWaitForAck_afterFltClear(enum LED_INDEX fltLed, enum LED_INDEX globalFaultLed);
void SI_flt_SM(unsigned char i);
void SI_almShortingType_wLatch_SM(unsigned char i, struct evtArr_s * evts);
void SI_alarm_enterAlarm(unsigned char i);
void SI_endAlarmEntry(unsigned char i);
//void SI_almShortingType_SM(unsigned char i, struct evtArr_s * evts, unsigned char eventOneSecondTick);

// Note: There can be up to 12 SI's -- SI1 to SI8 are full and have LED's; SI9 to SI12 are only shorting and have no LED's

//void SI_silentStatusChange();
//void SI_statusChange();
//void SI_supervisory();
//void SI_almEvac();
//void SI_almNoGA();
//void SI_almNorm();

void SI_24VOutput_init(void);
//void SI_24VOutput_set(enum SI_X_mask si);
//void SI_24VOutput_clear(enum SI_X_mask si);
int  SI_24VOutput_CheckAndDrive(void);
void SI_24VOutput_initP(struct SI * pSI, unsigned char gpioMask);
//void SI_24VOutput_test2(void);
void SI_24VOutput_test(void);

void SI_24VOutputEnable_init(void);
void SI_24VOutputEnable_test(void);

void SI_TestADport_init(void);
void SI_TestADport_On(void);
void SI_TestADport_Off(void);
void SI_TestADport_toggle(void);
void SI_TestADport(void);

void SI_TestADport_On(void);
void SI_TestADport_Off(void);
void SI_TestADport_toggle(void);
void SI_TestADport(void);


void test_so_faultSequence_updateTimer(void);
void test_so_faultSequence(void);



void SI_threadInfo_init(struct SI_threadInfo_t * me, enum LED_INDEX alarm, enum LED_INDEX fault, enum LED_INDEX gblAlm)
{
	me->adcState = SI_ADC_NORMAL;
	me->alarmState = SI_STATE_IDLE;
	me->faultState = SI_STATE_IDLE;
	me->alarmLed = alarm;
	me->faultLed = fault;
	me->globalAlarmLed = gblAlm;
	me->globalFaultLed = LED_TROUBLE;
	me->adcCount = 0;
	me->oneSecTickCount = 0;
	me->isAcked = 0;
	me->inReset = 0;
//	me->pSI = &configMemRAM.si[alarm-LED_SI_1_Alm];
	me->pSI = (struct SI *)&pConfigMemRAM->si[alarm-LED_SI_1_Alm];
}

void SI_threadInfo_setGlobalLed(struct SI_threadInfo_t * me, enum LED_INDEX gblAlm)
{
	me->globalAlarmLed = gblAlm;
}
void SI_threadInfo_reset(struct SI_threadInfo_t * me)
{
	me->adcState = SI_ADC_NORMAL;
	me->alarmState = SI_STATE_IDLE;
	me->faultState = SI_STATE_IDLE;
	me->adcCount = 0;
	me->oneSecTickCount = 0;
	me->isAcked = 0;
	me->inReset = 0;
}
void SI_init (void)
{
	int i;
	enum LED_INDEX alm = LED_SI_1_Alm;
	enum LED_INDEX flt = LED_SI_1_Flt;

	if (RTN_SUCCESS == isValidConfigSaved(0))
	{
		enum LED_INDEX gblAlm;
		for (i=0; i<8; i++)
		{
			if ((pConfigMemRAM->si[i].fxn == SI_Fxn_ALARM_NORMAL_GA)||(pConfigMemRAM->si[i].fxn == SI_Fxn_ALARM_SKIP_TO_EVAC)||(pConfigMemRAM->si[i].fxn == SI_Fxn_ALARM_NO_GA))
			{
				gblAlm = LED_ALARMS;
			}
			else if (pConfigMemRAM->si[i].fxn == SI_Fxn_SUPERVISORY)
			{
				gblAlm = LED_SUPER;
			}
			else
			{
				gblAlm = LED_noGlobalAlmLed;
			}
			SI_threadInfo_init(&SI_threadInfo[i], alm++, flt++, gblAlm);
		}
	}
	else
	{
		for (i=0; i<8; i++)
		{
			SI_threadInfo_init(&SI_threadInfo[i], alm++, flt++, LED_ALARMS);
		}
	}
//	SI_threadInfo_init(&SI_threadInfo[0], LED_SI_1_Alm, LED_SI_1_Flt, LED_ALARMS);
//	SI_threadInfo_init(&SI_threadInfo[1], LED_SI_2_Alm, LED_SI_2_Flt, LED_SUPER);
//	SI_threadInfo_init(&SI_threadInfo[2], LED_SI_3_Alm, LED_SI_3_Flt, LED_ALARMS);
//	SI_threadInfo_init(&SI_threadInfo[3], LED_SI_4_Alm, LED_SI_4_Flt, LED_ALARMS);
//	SI_threadInfo_init(&SI_threadInfo[4], LED_SI_5_Alm, LED_SI_5_Flt, LED_ALARMS);
//	SI_threadInfo_init(&SI_threadInfo[5], LED_SI_6_Alm, LED_SI_6_Flt, LED_ALARMS);
//	SI_threadInfo_init(&SI_threadInfo[6], LED_SI_7_Alm, LED_SI_7_Flt, LED_ALARMS);
//	SI_threadInfo_init(&SI_threadInfo[7], LED_SI_8_Alm, LED_SI_8_Flt, LED_ALARMS);

	LED_setMode(MODE_NORMAL);

	BTN_btnEvent_init();

	BTN_btnDebounce_init(/*&ACK, */		BTN_ACK, 		6, eBtnAck);
	BTN_btnDebounce_init(/*&RESET, */	BTN_RESET, 		6, eBtnReset);
	BTN_btnDebounce_init(/*&LAMP, */	BTN_LAMP_TEST, 	20, eBtnLampTest);
	BTN_btnDebounce_init(/*&SVC, */		BTN_SERVICE_MODE, 20, eBtnSvcMode);
	BTN_btnDebounce_init(/*&GA_ON, */	BTN_GA_ON, 		6, eBtnGAon);
	BTN_btnDebounce_init(/*&GA_OFF, */	BTN_GA_OFF, 	6, eBtnGAoff);
	BTN_btnDebounce_init(/*&GA_OFF, */	BTN_WARNING, 	6, eBtnWarning);

	SI_24VOutput_init();
	SI_24VOutputEnable_init();

	if (RTN_SUCCESS == isValidConfigSaved(0))
	{
		SI_24VOutput_CheckAndDrive();
	}

	SI_TestADport_init();
	SI_init25msTimerISR();
	SIadc_adc12_init_sequence(); //	SIadc_adc12_init_repeated();
}
void SI_init25msTimerISR(void)
{
	TA1CCTL0 = OUTMOD_7;	// select Timer A1 to be mode 7, reset/set
  	TA1CCR0 = UPDATE_STATE_TIMER;		// set interrupt period
  	TA1EX0 = TIMER_TA1EX0;
  	TA1CTL = TIMER_CTL;//TASSEL_2 + MC__UPDOWN; // select clock (SMCLK) and mode control (UP)
}
void SI_disable25msISR(void)
{
	SIadc_disableInterrupts();
	TA1CCTL0 &= ~CCIE;
}
void SI_enable25msISR(void)
{
	SIadc_enableInterrupts();
	TA1CCTL0 |= CCIE;
}
void SI_24VOutput_init(void)
{
	GPIO_setAsOutputPin(SI_24V_OUT_PORT, SI_24V_OUT_PIN_MASK);
	GPIO_setOutputLowOnPin(SI_24V_OUT_PORT, SI_24V_OUT_PIN_MASK);
}
void SI_24VOutput_set(enum SI_X_mask si)
{
	GPIO_setOutputHighOnPin(SI_24V_OUT_PORT, si);
}
void SI_24VOutput_clear(enum SI_X_mask si)
{
	GPIO_setOutputLowOnPin(SI_24V_OUT_PORT, si);
}
int  SI_24VOutput_CheckAndDrive(void)
{
	int i;
	unsigned char mask = 0;
	SI_24VOutput_init();
	SI_24VOutputEnable_init();

	if (RTN_SUCCESS != isValidConfigSaved(0))
	{
		return -1;
	}
	for (i=0; i<SI_ACTIVE; i++)
	{
		if (SI_Fxn_INHIBIT_INPUT != pConfigMemRAM->si[i].fxn)
		{
			mask |= 1<<i;
		}
	}
	if (mask)
	{
		GPIO_setOutputHighOnPin(SI_24_OUT_ENABLE_PORT, SI_24_OUT_ENABLE_PIN);
		GPIO_setOutputHighOnPin(SI_24V_OUT_PORT, mask);
	}
	return 0;
}
void SI_24VOutput_initP(struct SI * pSI, unsigned char gpioMask)
{
	unsigned char mask = 0;
	if (SI_Fxn_INHIBIT_INPUT != pSI->fxn)//(!pSI->fxn&0x1)
		mask |= gpioMask;
	GPIO_setAsOutputPin(SI_24V_OUT_PORT, SI_24V_OUT_PIN_MASK);
	GPIO_setOutputLowOnPin(SI_24V_OUT_PORT, SI_24V_OUT_PIN_MASK);
//	return mask;
}
void SI_24VOutput_test2(void)
{
	SI_24VOutput_init();
	int i;
	SI_24VOutput_set((enum SI_X_mask)1<<0);
	SI_24VOutput_set((enum SI_X_mask)1<<1);
	SI_24VOutput_clear((enum SI_X_mask)1<<1);
	SI_24VOutput_clear((enum SI_X_mask)1<<0);
	for (i=0; i<8; i++)
	{
		SI_24VOutput_set((enum SI_X_mask)1<<i);
		SI_24VOutput_clear((enum SI_X_mask)1<<i);
	}
}
void SI_24VOutput_test(void)
{
	SI_24VOutput_init();
	GPIO_setOutputHighOnPin(SI_24V_OUT_PORT, SI_24V_OUT_PIN_MASK);
	GPIO_setOutputLowOnPin(SI_24V_OUT_PORT, SI_24V_OUT_PIN_MASK);
	GPIO_setOutputHighOnPin(SI_24V_OUT_PORT, SI_1_24V_OUT_PIN);
	GPIO_setOutputLowOnPin(SI_24V_OUT_PORT, SI_1_24V_OUT_PIN);

	GPIO_setOutputHighOnPin(SI_24V_OUT_PORT, SI_24V_OUT_PIN_MASK);
}
void SI_24VOutputEnable_init(void)
{
	GPIO_setAsOutputPin(SI_24_OUT_ENABLE_PORT, SI_24_OUT_ENABLE_PIN);
	GPIO_setOutputLowOnPin(SI_24_OUT_ENABLE_PORT, SI_24_OUT_ENABLE_PIN);
}
void SI_24VOutputEnable_test(void)
{
	SI_24VOutputEnable_init();
	GPIO_setOutputHighOnPin(SI_24_OUT_ENABLE_PORT, SI_24_OUT_ENABLE_PIN);
	GPIO_setOutputLowOnPin(SI_24_OUT_ENABLE_PORT, SI_24_OUT_ENABLE_PIN);
	GPIO_setOutputHighOnPin(SI_24_OUT_ENABLE_PORT, SI_24_OUT_ENABLE_PIN);
}
void SI_TestADport_init(void)
{
	GPIO_setAsInputPin(SI_TEST_AD_PORT, SI_TEST_AD_PIN);
//	GPIO_setAsOutputPin(SI_TEST_AD_PORT, SI_TEST_AD_PIN);
//	GPIO_setOutputLowOnPin(SI_TEST_AD_PORT, SI_TEST_AD_PIN);
}
void SI_TestADport_On(void)
{
	GPIO_setAsOutputPin(SI_TEST_AD_PORT, SI_TEST_AD_PIN);
	GPIO_setOutputHighOnPin(SI_TEST_AD_PORT, SI_TEST_AD_PIN);
}
void SI_TestADport_Off(void)
{
//	GPIO_setOutputLowOnPin(SI_TEST_AD_PORT, SI_TEST_AD_PIN);
	GPIO_setAsInputPin(SI_TEST_AD_PORT, SI_TEST_AD_PIN);
}
void SI_TestADport_toggle(void)
{
	static unsigned char turn = 0;
	if (turn == 0)
	{
		turn = 1;
		SI_TestADport_On();
	}
	else
	{
		turn = 0;
		SI_TestADport_Off();
	}
}
void SI_TestADport(void)
{
	SI_TestADport_init();
	GPIO_setOutputHighOnPin(SI_TEST_AD_PORT, SI_TEST_AD_PIN);
	GPIO_setOutputLowOnPin(SI_TEST_AD_PORT, SI_TEST_AD_PIN);

}
void SI_globalLedLogic(void)
{
	enum LED_INDEX i;
	enum RATES almRate = RATE_OFF;
	enum RATES fltRate = RATE_OFF;

	for (i=LED_SI_1_Alm; i<=LED_SI_8_Alm; i++)
	{
		if (LED_getRate(i) > RATE_ON)
		{
//			SI_threadInfo[i-LED_SI_1_Alm].alarmState;
			almRate = RATE_FAST;
			break;
		}
		if (LED_getRate(i) == RATE_ON)
			almRate = RATE_ON;
	}
	for (i=LED_SI_1_Flt; i<=LED_SI_8_Flt; i++)
	{
		if (LED_getRate(i) > RATE_ON)
		{
			fltRate = RATE_SLOW;
			break;
		}
		if (LED_getRate(i) == RATE_ON)
			fltRate = RATE_ON;
	}
	if ((LED_getRate(LED_ALARMS)> RATE_ON) && (almRate == RATE_ON))
	{
		LED_setRate(LED_ALARMS, RATE_ON);
	}
	if ((LED_getRate(LED_SUPER)> RATE_ON) && (almRate == RATE_ON))
	{
		LED_setRate(LED_SUPER, RATE_ON);
	}
	if ((LED_getRate(LED_TROUBLE)> RATE_ON) && (fltRate == RATE_ON))
	{
		LED_setRate(LED_TROUBLE, RATE_ON);
	}
}
void SI_relayHelper(enum LED_INDEX almLed, enum LED_INDEX globalAlarmLed, enum Relay_Setting relaySetting)
{
	if (globalAlarmLed == LED_ALARMS)
	{
		REL_resourceArray_requestRelay(Relay_Alarm, almLed, relaySetting);
	}
	else if (globalAlarmLed == LED_SUPER)
	{
		REL_resourceArray_requestRelay(Relay_Fault, almLed, relaySetting);
	}
}
/*typedef struct {
	enum SI_type myType;
	enum SI_ADC_STATE status_1;
	enum SI_ADC_STATE status_2;
	enum SI_ADC_STATE status_3;
	enum SI_ADC_STATE status_4;
	enum SI_ADC_STATE status_5;
} AdcToStatus_t;

AdcToStatus_t SI_adcToStatus [] = {
	 			0 to 249	  250 to 584    585 to 999   1000 to 4049   4050 to 4095
	{SI_TYPE1, SI_ADC_ALARM, SI_ADC_FAULT, SI_ADC_FAULT, SI_ADC_NORMAL, SI_ADC_FAULT},
	{SI_TYPE2, SI_ADC_FAULT, SI_ADC_ALARM, SI_ADC_FAULT, SI_ADC_NORMAL, SI_ADC_FAULT},

	{SI_TYPE3, SI_ADC_NORMAL, SI_ADC_FAULT, SI_ADC_FAULT, SI_ADC_ALARM, SI_ADC_FAULT},
	{SI_TYPE4, SI_ADC_FAULT, SI_ADC_NORMAL, SI_ADC_FAULT, SI_ADC_ALARM, SI_ADC_FAULT},
	{SI_TYPE5, SI_ADC_NORMAL, SI_ADC_FAULT, SI_ADC_FAULT, SI_ADC_ALARM, SI_ADC_FAULT},

	{SI_TYPE6, SI_ADC_FAULT, SI_ADC_NORMAL, SI_ADC_FAULT, SI_ADC_ALARM, SI_ADC_FAULT},
	{SI_TYPE7, SI_ADC_FAULT, SI_ADC_NORMAL, SI_ADC_FAULT, SI_ADC_ALARM, SI_ADC_FAULT},
	{SI_TYPE8, SI_ADC_FAULT, SI_ADC_NORMAL, SI_ADC_FAULT, SI_ADC_ALARM, SI_ADC_FAULT},

	{SI_TYPE9, SI_ADC_ALARM, SI_ADC_NORMAL, SI_ADC_FAULT, SI_ADC_FAULT, SI_ADC_FAULT}
};
void SI_adcToStatus_adcToStatus(unsigned int *adcCounts, enum SI_ADC_STATE * state, enum SI_type myType)
{
	int i;
	if (*adcCounts > 4095)
	{
		// error
	}
	for (i=adcRange_low; i<adcRange_size; i++)
	{
		if ((*adcCounts >= adcRange[i].low) && (*adcCounts <= adcRange[i].high))
		{
			*state = SI_adcToStatus[myType].status_1;//rangeData[i].status;
			break;
		}
	}
}*/
typedef struct {
	unsigned int low;
	unsigned int high;
}AdcRange_t;
typedef struct {
	unsigned int low;
	unsigned int high;
//	AdcRange_t adcRange;
//	unsigned int status;
	enum SI_ADC_STATE status;
} RangeData_t;
AdcRange_t adcRange [] = {
	{0, 249},
	{250, 584},
	{585, 999},
	{1000, 4049},
	{4050, 4095}
};
typedef enum {
	adcRange_1,
	adcRange_low = adcRange_1,
	adcRange_2,
	adcRange_3,
	adcRange_4,
	adcRange_high,
	adcRange_5 = adcRange_high,
	adcRange_size
} eAdcRange;
//typedef RangeData_t SI_inputTypeRecord_t [5];
typedef struct {						// is 5 records sufficient?
	RangeData_t rangeRecord [5];
//	unsigned int size;
}SI_inputTypeRecord_t;
SI_inputTypeRecord_t SI_inputType_1  = {{  // where should the proper home be???
		{4050, 4095, SI_ADC_FAULT},
		{1000, 4049, SI_ADC_NORMAL},
		{585, 999, SI_ADC_FAULT},
		{250, 584, SI_ADC_FAULT},
		{0, 249, SI_ADC_ALARM}
}};//,5};
SI_inputTypeRecord_t SI_inputType_2  = {{
	{4050, 4095, SI_ADC_FAULT},
	{1000, 4049, SI_ADC_NORMAL},
	{585, 999, SI_ADC_FAULT},
	{250, 584, SI_ADC_ALARM},
	{0, 249, SI_ADC_FAULT}
}};
SI_inputTypeRecord_t SI_inputType_3  = {{
	{4050, 4095, SI_ADC_FAULT},
	{1000, 4049, SI_ADC_ALARM},
	{585, 999, SI_ADC_FAULT},
	{250, 584, SI_ADC_FAULT},
	{0, 249, SI_ADC_NORMAL}
}};
SI_inputTypeRecord_t SI_inputType_4  = {{
	{4050, 4095, SI_ADC_FAULT},		// undefined
	{1000, 4049, SI_ADC_ALARM},		// shorted
	{585, 999, SI_ADC_FAULT},		// undefined
	{250, 584, SI_ADC_NORMAL},		// open
	{0, 249, SI_ADC_FAULT}			// eol missing
}};
#define NEW_ADC_RANGE 1

#if NEW_ADC_RANGE
SI_inputTypeRecord_t SI_inputType_5  = {{
	{4050, 4095, SI_ADC_FAULT},
	{3000, 4049, SI_ADC_FAULT},
	{585, 2999, SI_ADC_ALARM},
	{250, 584, SI_ADC_FAULT},
	{0, 249, SI_ADC_NORMAL}
}};
SI_inputTypeRecord_t SI_inputType_6  = {{
	{4050, 4095, SI_ADC_FAULT},
	{3000, 4049, SI_ADC_FAULT}, // short @ 3429, 4.34V
	{585, 2999, SI_ADC_ALARM}, // @ 2793, 3.54V
	{250, 584, SI_ADC_NORMAL}, // @ 519, 0.6V
	{0, 249, SI_ADC_FAULT}     // open @ 0, 0V
}};
SI_inputTypeRecord_t SI_inputType_7  = {{
	{4050, 4095, SI_ADC_FAULT},
	{3000, 4049, SI_ADC_ALARM},
	{585, 2999, SI_ADC_ALARM},
	{250, 584, SI_ADC_FAULT},
	{0, 249, SI_ADC_NORMAL}
}};
SI_inputTypeRecord_t SI_inputType_8  = {{
	{4050, 4095, SI_ADC_FAULT},
	{3000, 4049, SI_ADC_ALARM}, // short @ 3429, 4.34V
	{585, 2999, SI_ADC_ALARM}, // @ 2793, 3.54V
	{250, 584, SI_ADC_NORMAL}, // @ 519, 0.6V
	{0, 249, SI_ADC_FAULT}     // open @ 0, 0V
}};
#else
SI_inputTypeRecord_t SI_inputType_5  = {{
	{4050, 4095, SI_ADC_FAULT},
	{1000, 4049, SI_ADC_ALARM},
	{585, 999, SI_ADC_FAULT},
	{250, 584, SI_ADC_FAULT},
	{0, 249, SI_ADC_NORMAL}
}};
SI_inputTypeRecord_t SI_inputType_6  = {{
	{4050, 4095, SI_ADC_FAULT},
	{1000, 4049, SI_ADC_ALARM},
	{585, 999, SI_ADC_FAULT},
	{250, 584, SI_ADC_NORMAL},
	{0, 249, SI_ADC_FAULT}
}};
SI_inputTypeRecord_t SI_inputType_7  = {{
	{4050, 4095, SI_ADC_FAULT},
	{1000, 4049, SI_ADC_ALARM},
	{585, 999, SI_ADC_FAULT},
	{250, 584, SI_ADC_NORMAL},
	{0, 249, SI_ADC_FAULT}
}};
SI_inputTypeRecord_t SI_inputType_8  = {{
	{4050, 4095, SI_ADC_FAULT},
	{1000, 4049, SI_ADC_ALARM},
	{585, 999, SI_ADC_FAULT},
	{250, 584, SI_ADC_NORMAL},
	{0, 249, SI_ADC_FAULT}
}};
#endif
SI_inputTypeRecord_t SI_inputType_9  = {{
	{4050, 4095, SI_ADC_FAULT},
	{1000, 4049, SI_ADC_FAULT},
	{585, 999, SI_ADC_FAULT},
	{250, 584, SI_ADC_NORMAL},
	{0, 249, SI_ADC_ALARM}
}};
//typedef RangeData_t SI_inputTypeRecord_t [5];
/*typedef struct {
	SI_inputTypeRecord_t * inputTypeRecord;
}SI_inputTypeTable_t;*/

SI_inputTypeRecord_t *pSI_inputTypeTable [] =  {
	&SI_inputType_1,
	&SI_inputType_2,
	&SI_inputType_3,
	&SI_inputType_4,
	&SI_inputType_5,
	&SI_inputType_6,
	&SI_inputType_7,
	&SI_inputType_8,
	&SI_inputType_9
};


/*
SI_inputTypeTable_t inputTypeTable [] {
	&SI_inputType_1,
	&SI_inputType_2
};
*/

/*SI_inputTypeRecord_t SI_inputTypeRecord  []= {
	{&SI_inputType_2[0], 5},
	{&SI_inputType_9, 5}
};*/
/*typedef struct {
	RangeData_t ** rangeData;
} SI_rangeRecord_t;

SI_rangeRecord_t rangeRecord [] = {
	&SI_inputType_1,
	&SI_inputType_2,
	&SI_inputType_3,
	&SI_inputType_4,
	&SI_inputType_5,
	&SI_inputType_6,
	&SI_inputType_7,
	&SI_inputType_8,
	&SI_inputType_9
};*/
//SI_adcToStatus_RangeData(&SI_threadInfo[i].adcCount, &SI_threadInfo[i].adcState, pSI_inputTypeTable[SI_threadInfo[i].pSI->InputType]);
//struct SI_threadInfo_t;
//void SI_adcToStatus_RangeData(unsigned int *adcCounts, enum SI_ADC_STATE * state, SI_inputTypeRecord_t * rangeData)
//enum SI_ADC_STATE adcState;
//enum SI_ADC_STATE adcStateTarget;
//unsigned char adcFilterCount; // for simple adc filter, count to SI_ADC_FILTER_COUNT before transition
void SI_adcToStatus_RangeDataFilt(unsigned int *adcCounts, struct SI_threadInfo_t *threadInfo, SI_inputTypeRecord_t * rangeData)
{
	int i;
	enum SI_ADC_STATE * state, *targetState, newState;
//	RangeData_t record = (RangeData_t)rangeData->rangeRecord;
	state = &threadInfo->adcState;
	targetState = &threadInfo->adcStateTarget;
	if (*adcCounts > 4095)
	{
		// error
	}
	for (i=0; i<5; i++)
	{
		if ((*adcCounts >= rangeData->rangeRecord[i].low) && (*adcCounts <= rangeData->rangeRecord[i].high))
		{

			newState = rangeData->rangeRecord[i].status;
			break;
		}
	}
	/* Reset if new adc state detected. newState could probably eliminated. */
	if (newState != *targetState){
		threadInfo->adcFilterCount = 0;
		*targetState = newState;
	}
	if (*targetState != *state){
		if (threadInfo->adcFilterCount++ == SI_ADC_FILTER_COUNT){
			threadInfo->adcFilterCount = 0;
			*state = *targetState;
		}
	}else{
		threadInfo->adcFilterCount = 0;
	}
}
void SI_adcToStatus_RangeData(unsigned int *adcCounts, enum SI_ADC_STATE * state, SI_inputTypeRecord_t * rangeData)
{
	int i;
//	RangeData_t record = (RangeData_t)rangeData->rangeRecord;
	if (*adcCounts > 4095)
	{
		// error
	}
	for (i=0; i<5; i++)
	{
		if ((*adcCounts >= rangeData->rangeRecord[i].low) && (*adcCounts <= rangeData->rangeRecord[i].high))
		{
			*state = rangeData->rangeRecord[i].status;
			break;
		}
	}
}
void SI_adcToStatus_type6(unsigned int *adcCounts, enum SI_ADC_STATE * state)
{
	if (*adcCounts < 250)//322)//1550)//1600)//2500)
	{
		*state = SI_ADC_FAULT;
	}
	else if (*adcCounts < 585)//485)//2500)//3000)
	{
		*state = SI_ADC_NORMAL;
	}
	else if (*adcCounts < 1000)//2168)//2900)
	{
		*state = SI_ADC_FAULT;//SI_ADC_ALARM;
	}
	else if (*adcCounts < 4050)//3286)//2900)
	{
		*state = SI_ADC_ALARM;
	}
	else
	{
		*state = SI_ADC_FAULT;
	}
}
void SI_adcToStatus_type4(unsigned int *adcCounts, enum SI_ADC_STATE * state)
{
	testPinPort8_off(TEST_SI_1_ALM);
	testPinPort8_off(TEST_SI_1_FLT);
	if (*adcCounts < 250)//322)//1550)//1600)//2500)
	{
		testPinPort8_on(TEST_SI_1_FLT);
		// fault, u7 port 1
		*state = SI_ADC_FAULT;
	}
	else if (*adcCounts < 585)//485)//2500)//3000)
	{
		// normal
		*state = SI_ADC_NORMAL;
	}
	else if (*adcCounts < 1000)//2168)//2900)
	{
		testPinPort8_on(TEST_SI_1_FLT);
		// alarm, u7 port 0
		*state = SI_ADC_FAULT;//SI_ADC_ALARM;
	}
	else if (*adcCounts < 4050)//3286)//2900)
	{
		testPinPort8_on(TEST_SI_1_ALM);
		// alarm, u7 port 0
		*state = SI_ADC_ALARM;
	}
	else
	{
		testPinPort8_on(TEST_SI_1_FLT);
		// fault, u7 port 1
		*state = SI_ADC_FAULT;
	}
}
void SI_alarmIDLE(enum LED_INDEX almLed, enum LED_INDEX globalAlarmLed)
{
	LED_setRate(almLed, RATE_OFF);
	//LED_setRate(globalAlarmLed, RATE_OFF);
	enum LED_GLOBAL_INDEX glob = globalLedToIndex(globalAlarmLed);// - LED_GLOBAL_BEGIN;
	LED_resourceArray_requestRate(glob, almLed, RATE_OFF);
	SI_relayHelper(almLed, globalAlarmLed, Relay_Off);
//	if (globalAlarmLed == LED_ALARMS)
//	{
//		REL_resourceArray_requestRelay(Relay_Alarm, almLed, Relay_Off);
////		Relay_set(Relay_Alarm, Relay_Off);
//	}
//	else if (globalAlarmLed == LED_SUPER)
//	{
//		REL_resourceArray_requestRelay(Relay_Fault, almLed, Relay_Off);
////		Relay_set(Relay_Fault, Relay_Off);
//	}
}
void SI_alarmEntryTimerFWS_waitForAck(enum LED_INDEX almLed, enum LED_INDEX globalAlarmLed)
{
	if (globalAlarmLed == LED_ALARMS)
	{
		LED_setRate(almLed, RATE_FAST);
		//LED_setRate(globalAlarmLed, RATE_FAST);
		enum LED_GLOBAL_INDEX glob = globalLedToIndex(globalAlarmLed);// - LED_GLOBAL_BEGIN;
		LED_resourceArray_requestRate(glob, almLed, RATE_FAST);
	}
	else if (globalAlarmLed == LED_SUPER)
	{
		LED_setRate(almLed, RATE_SLOW);
		//LED_setRate(globalAlarmLed, RATE_SLOW);
		enum LED_GLOBAL_INDEX glob = globalLedToIndex(globalAlarmLed);// - LED_GLOBAL_BEGIN;
		LED_resourceArray_requestRate(glob, almLed, RATE_SLOW);
	}
	else
	{
		LED_setRate(almLed, RATE_SLOW);
	}
}
void SI_alarmWaitForAck_nonLatchAlmClear(enum LED_INDEX almLed, enum LED_INDEX globalAlarmLed)
{
	SI_alarmEntryTimerFWS_waitForAck(almLed, globalAlarmLed);
//	LED_setRate(almLed, RATE_FAST);
//	LED_setRate(globalAlarmLed, RATE_FAST);
//	enum LED_GLOBAL_INDEX glob = globalLedToIndex(globalAlarmLed);// - LED_GLOBAL_BEGIN;
//	LED_resourceArray_requestRate(glob, almLed, RATE_FAST);
	SI_relayHelper(almLed, globalAlarmLed, Relay_Off);
//	if (globalAlarmLed == LED_ALARMS)
//	{
//		REL_resourceArray_requestRelay(Relay_Alarm, almLed, Relay_Off);
////		Relay_set(Relay_Alarm, Relay_On);
//	}
//	else if (globalAlarmLed == LED_SUPER)
//	{
//		REL_resourceArray_requestRelay(Relay_Fault, almLed, Relay_Off);
////		Relay_set(Relay_Fault, Relay_On);
//	}
//	SOSZ_notifySOSZ_SILoAlm(1<<i);
}
void SI_alarmWaitForAck(enum LED_INDEX almLed, enum LED_INDEX globalAlarmLed)
{
	SI_alarmEntryTimerFWS_waitForAck(almLed, globalAlarmLed);
//	LED_setRate(almLed, RATE_FAST);
//	LED_setRate(globalAlarmLed, RATE_FAST);
//	enum LED_GLOBAL_INDEX glob = globalLedToIndex(globalAlarmLed);// - LED_GLOBAL_BEGIN;
//	LED_resourceArray_requestRate(glob, almLed, RATE_FAST);
	SI_relayHelper(almLed, globalAlarmLed, Relay_On);
//	if (globalAlarmLed == LED_ALARMS)
//	{
//		REL_resourceArray_requestRelay(Relay_Alarm, almLed, Relay_On);
////		Relay_set(Relay_Alarm, Relay_On);
//	}
//	else if (globalAlarmLed == LED_SUPER)
//	{
//		REL_resourceArray_requestRelay(Relay_Fault, almLed, Relay_On);
////		Relay_set(Relay_Fault, Relay_On);
//	}
//	SOSZ_notifySOSZ_SILoAlm(1<<i);
}
void SI_alarmWaitForResetOrFltClear(enum LED_INDEX almLed, enum LED_INDEX globalAlarmLed)
{
	LED_setRate(almLed, RATE_ON);

	//LED_setRate(globalAlarmLed, RATE_ON);
	enum LED_GLOBAL_INDEX glob = globalLedToIndex(globalAlarmLed);// - LED_GLOBAL_BEGIN;
	LED_resourceArray_requestRate(glob, almLed, RATE_ON);
	SI_relayHelper(almLed, globalAlarmLed, Relay_On);
//	if (globalAlarmLed == LED_ALARMS)
//	{
//		REL_resourceArray_requestRelay(Relay_Alarm, almLed, Relay_On);
////		Relay_set(Relay_Alarm, Relay_On);
//	}
//	else if (globalAlarmLed == LED_SUPER)
//	{
//		REL_resourceArray_requestRelay(Relay_Fault, almLed, Relay_On);
////		Relay_set(Relay_Fault, Relay_On);
//	}
}
void SI_alarmWaitForAck_afterResetOrFltClear(enum LED_INDEX almLed, enum LED_INDEX globalAlarmLed)
{
	//LED_setRate(globalAlarmLed, RATE_OFF);
	enum LED_GLOBAL_INDEX glob = globalLedToIndex(globalAlarmLed);// - LED_GLOBAL_BEGIN;
	LED_resourceArray_requestRate(glob, almLed, RATE_OFF);
	SOSZ_clearSOSZ_SILoAlm(1<<(almLed-LED_SI_1_Alm));
	SI_relayHelper(almLed, globalAlarmLed, Relay_Off);
	if (globalAlarmLed == LED_ALARMS)
	{
		LED_setRate(almLed, RATE_SLOW);
//		REL_resourceArray_requestRelay(Relay_Alarm, almLed, Relay_Off);
//		Relay_set(Relay_Alarm, Relay_Off);
	}
	else if (globalAlarmLed == LED_SUPER)
	{
		LED_setRate(almLed, RATE_SLOW_SLOW);
//		REL_resourceArray_requestRelay(Relay_Fault, almLed, Relay_Off);
//		Relay_set(Relay_Fault, Relay_Off);
	}
	else
	{
		LED_setRate(almLed, RATE_SLOW);
	}
//	SOSZ_clearSOSZ_SILoAlm(1<<i);
}

void SI_faultIDLE(enum LED_INDEX fltLed, enum LED_INDEX globalFaultLed)
{
	LED_setRate(fltLed, RATE_OFF);
	LED_setRate(globalFaultLed, RATE_OFF);
	enum LED_GLOBAL_INDEX glob = globalLedToIndex(globalFaultLed);// - LED_GLOBAL_BEGIN;
	LED_resourceArray_requestRate(glob, fltLed, RATE_OFF);
	REL_resourceArray_requestRelay(Relay_Fault, fltLed, Relay_Off);
//	Relay_set(Relay_Fault, Relay_Off);
}
void SI_faultWaitForAck(enum LED_INDEX fltLed, enum LED_INDEX globalFaultLed)
{
	LED_setRate(fltLed, RATE_SLOW);
	LED_setRate(globalFaultLed, RATE_SLOW);
	enum LED_GLOBAL_INDEX glob = globalLedToIndex(globalFaultLed);// - LED_GLOBAL_BEGIN;
	LED_resourceArray_requestRate(glob, fltLed, RATE_SLOW);
	REL_resourceArray_requestRelay(Relay_Fault, fltLed, Relay_On);
//	Relay_set(Relay_Fault, Relay_On);
}
void SI_faultWaitForFltClear(enum LED_INDEX fltLed, enum LED_INDEX globalFaultLed)
{
	LED_setRate(fltLed, RATE_ON);
	LED_setRate(globalFaultLed, RATE_ON);
	enum LED_GLOBAL_INDEX glob = globalLedToIndex(globalFaultLed);// - LED_GLOBAL_BEGIN;
	LED_resourceArray_requestRate(glob, fltLed, RATE_ON);
	REL_resourceArray_requestRelay(Relay_Fault, fltLed, Relay_On);
//	Relay_set(Relay_Fault, Relay_On);
}
void SI_faultWaitForAck_afterFltClear(enum LED_INDEX fltLed, enum LED_INDEX globalFaultLed)
{
	LED_setRate(fltLed, RATE_SLOW_SLOW);
	LED_setRate(globalFaultLed, RATE_OFF);
	enum LED_GLOBAL_INDEX glob = globalLedToIndex(globalFaultLed);// - LED_GLOBAL_BEGIN;
	LED_resourceArray_requestRate(glob, fltLed, RATE_OFF);
	REL_resourceArray_requestRelay(Relay_Fault, fltLed, Relay_Off);
//	Relay_set(Relay_Fault, Relay_Off);
}
void SI_flt_SM(unsigned char i)
{
	switch (SI_threadInfo[i].faultState)
	{
		case SI_STATE_IDLE:
			if (SI_threadInfo[i].adcState == SI_ADC_FAULT)
			{
				SI_threadInfo[i].faultState = SI_STATE_faultWaitForAck;
				SI_faultWaitForAck(SI_threadInfo[i].faultLed, SI_threadInfo[i].globalFaultLed);
				break;
			}
			__no_operation();
			break;
		case SI_STATE_faultWaitForAck:
//			if (SI_ackBtnLogic() == SI_threadInfo[i].faultLed)
			if (evt_yes == BTN_btnEvent_get(eBtnAck))
			{
				BTN_btnEvent_consume(eBtnAck);
				if (SI_threadInfo[i].adcState == SI_ADC_FAULT)
				{
					SI_threadInfo[i].faultState = SI_STATE_faultWaitForFltClear;
					SI_faultWaitForFltClear(SI_threadInfo[i].faultLed, SI_threadInfo[i].globalFaultLed);

				}
				else //if (SI_threadInfo[i].adcState == SI_ADC_NORMAL)
				{
					SI_threadInfo[i].faultState = SI_STATE_faultWaitForAck_afterFltClear;
					SI_faultWaitForAck_afterFltClear(SI_threadInfo[i].faultLed, SI_threadInfo[i].globalFaultLed);
				}
			}
			break;
		case SI_STATE_faultWaitForFltClear:
			if (SI_threadInfo[i].adcState == SI_ADC_NORMAL)
			{
				SI_threadInfo[i].faultState = SI_STATE_faultWaitForAck_afterFltClear;
				SI_faultWaitForAck_afterFltClear(SI_threadInfo[i].faultLed, SI_threadInfo[i].globalFaultLed);

			}
			break;
		case SI_STATE_faultWaitForAck_afterFltClear:
			if (SI_threadInfo[i].adcState == SI_ADC_FAULT)
			{
				SI_threadInfo[i].faultState = SI_STATE_faultWaitForAck;
				SI_faultWaitForAck(SI_threadInfo[i].faultLed, SI_threadInfo[i].globalFaultLed);
				break;
			}
//			if (SI_ackBtnLogic() == SI_threadInfo[i].faultLed)
			if (evt_yes == BTN_btnEvent_get(eBtnAck))
			{
				BTN_btnEvent_consume(eBtnAck);
				SI_threadInfo[i].faultState = SI_STATE_IDLE;
				SI_faultIDLE(SI_threadInfo[i].faultLed, SI_threadInfo[i].globalFaultLed);
			}
			break;
	}
}
void SI_almShortingType_wLatch_SM(unsigned char i, struct evtArr_s * evts)
{
	__no_operation();
}

void SI_alarm_enterAlarm(unsigned char i)
{
	if (SI_threadInfo[i].pSI->AlarmEntryTimer)
	{
		SI_threadInfo[i].oneSecTickCount = 0;//SI_threadInfo[i].pSI->AlarmEntryTimer;
		if (SI_threadInfo[i].pSI->InputType <= SI_TYPE4) // is shorting type
		{
			if(SI_threadInfo[i].pSI->FWSEntryTimerEnable)
			{
				SI_threadInfo[i].alarmState = SI_STATE_alarmEntryTimerFWS_waitForAck;
				SI_alarmEntryTimerFWS_waitForAck(SI_threadInfo[i].alarmLed, SI_threadInfo[i].globalAlarmLed);
				return;
			}
		}
		SI_threadInfo[i].alarmState = SI_STATE_alarmEntryTimer;
		return;
	}
	SI_threadInfo[i].alarmState = SI_STATE_alarmWaitForAck;
	SI_alarmWaitForAck(SI_threadInfo[i].alarmLed, SI_threadInfo[i].globalAlarmLed);
	SOSZ_notifySOSZ_SILoAlm(1<<i);
	return;
}
void SI_endAlarmEntry(unsigned char i)
{
	if (SI_threadInfo[i].adcState == SI_ADC_ALARM)
	{
		SI_threadInfo[i].alarmState = SI_STATE_alarmWaitForAck;
		SI_alarmWaitForAck(SI_threadInfo[i].alarmLed, SI_threadInfo[i].globalAlarmLed);
		SOSZ_notifySOSZ_SILoAlm(1<<i);
	}
	else
	{
		SI_threadInfo[i].alarmState = SI_STATE_IDLE;
		SI_alarmIDLE(SI_threadInfo[i].alarmLed, SI_threadInfo[i].globalAlarmLed);
	}
}
void SI_almShortingType_SM(unsigned char i, struct evtArr_s * evts, unsigned char eventOneSecondTick)
{
	switch (SI_threadInfo[i].alarmState)
	{
		case SI_STATE_IDLE:
			SOSZ_clearSOSZ_SILoAlm(1<<i);
			SI_alarmIDLE(SI_threadInfo[i].alarmLed, SI_threadInfo[i].globalAlarmLed);
			if (SI_threadInfo[i].adcState == SI_ADC_ALARM)
			{
				SI_alarm_enterAlarm(i);
			}
			break;
		case SI_STATE_alarmEntryTimerFWS_waitForAck:
			if (eventOneSecondTick)
			{
				if (SI_threadInfo[i].oneSecTickCount++ == SI_threadInfo[i].pSI->AlarmEntryTimer)
				{
					SI_endAlarmEntry(i);
					break;
				}
			}
			if (evt_yes == BTN_btnEvent_get(eBtnAck))
			{
				BTN_btnEvent_consume(eBtnAck);
				SI_threadInfo[i].alarmState = SI_STATE_alarmEntryTimerFWS_Acked;
				SI_alarmWaitForResetOrFltClear(SI_threadInfo[i].alarmLed, SI_threadInfo[i].globalAlarmLed);
			}
//				SOSZ_notifySOSZ_SILoAlm(1<<i);
			break;
		case SI_STATE_alarmEntryTimerFWS_Acked:
			if (eventOneSecondTick)
			{
				if (SI_threadInfo[i].oneSecTickCount++ == SI_threadInfo[i].pSI->AlarmEntryTimer)
				{
					if (SI_threadInfo[i].adcState == SI_ADC_ALARM)
					{
						SI_threadInfo[i].alarmState = SI_STATE_alarmWaitForResetOrFltClear;
						SI_alarmWaitForAck(SI_threadInfo[i].alarmLed, SI_threadInfo[i].globalAlarmLed);
						SOSZ_notifySOSZ_SILoAlm(1<<i);
						break;
					}
					else
					{
						SI_threadInfo[i].alarmState = SI_STATE_alarmWaitForAck_afterResetOrFltClear;
						SI_alarmWaitForResetOrFltClear(SI_threadInfo[i].alarmLed, SI_threadInfo[i].globalAlarmLed);
						break;
					}
				}
			}
				break;
		case SI_STATE_alarmEntryTimer:
			if (eventOneSecondTick)
			{
				if (SI_threadInfo[i].oneSecTickCount++ == SI_threadInfo[i].pSI->AlarmEntryTimer)
				{
					SI_endAlarmEntry(i);
					break;
				}
			}
			break;
		case SI_STATE_alarmWaitForAck:
			SI_alarmWaitForAck(SI_threadInfo[i].alarmLed, SI_threadInfo[i].globalAlarmLed);
			if (evt_yes == BTN_btnEvent_get(eBtnAck))
			{
				BTN_btnEvent_consume(eBtnAck);
				if ((SI_threadInfo[i].adcState == SI_ADC_ALARM)||(SI_threadInfo[i].pSI->SWLatch))
				{
					SI_threadInfo[i].alarmState = SI_STATE_alarmWaitForResetOrFltClear;
					SI_alarmWaitForResetOrFltClear(SI_threadInfo[i].alarmLed, SI_threadInfo[i].globalAlarmLed);
					break;
				}
				else if (SI_threadInfo[i].adcState == SI_ADC_NORMAL)
				{
					SI_threadInfo[i].alarmState = SI_STATE_alarmWaitForAck_afterResetOrFltClear;
					SI_alarmWaitForAck_afterResetOrFltClear(SI_threadInfo[i].alarmLed, SI_threadInfo[i].globalAlarmLed);
					break;
				}
			}
			else if ((SI_threadInfo[i].adcState == SI_ADC_NORMAL) && (SI_threadInfo[i].pSI->SWLatch == SI_latch_notLatched))
			{
				SI_alarmWaitForAck_nonLatchAlmClear(SI_threadInfo[i].alarmLed, SI_threadInfo[i].globalAlarmLed);
				SOSZ_clearSOSZ_SILoAlm(1<<i);
			}
			else
			{
				SOSZ_notifySOSZ_SILoAlm(1<<i);
			}
			break;
		case SI_STATE_alarmWaitForResetOrFltClear:
			if (SI_threadInfo[i].pSI->SWLatch)
			{
				if (evt_yes == BTN_btnEvent_get(eBtnReset))
				{
					if (SI_threadInfo[i].adcState == SI_ADC_NORMAL)
					{
						SI_threadInfo[i].alarmState = SI_STATE_alarmWaitForAck_afterResetOrFltClear;
						SI_alarmWaitForAck_afterResetOrFltClear(SI_threadInfo[i].alarmLed, SI_threadInfo[i].globalAlarmLed);
						break;
					}
				}
			}
			else if (SI_threadInfo[i].adcState == SI_ADC_NORMAL)
			{
				SI_threadInfo[i].alarmState = SI_STATE_alarmWaitForAck_afterResetOrFltClear;
				SI_alarmWaitForAck_afterResetOrFltClear(SI_threadInfo[i].alarmLed, SI_threadInfo[i].globalAlarmLed);
				break;
			}
			SOSZ_notifySOSZ_SILoAlm(1<<i);
			break;
		case SI_STATE_alarmWaitForAck_afterResetOrFltClear:
			if (SI_threadInfo[i].adcState == SI_ADC_ALARM)
			{
				SI_threadInfo[i].alarmState = SI_STATE_alarmWaitForAck;
				SI_alarmWaitForAck(SI_threadInfo[i].alarmLed, SI_threadInfo[i].globalAlarmLed);
				SOSZ_notifySOSZ_SILoAlm(1<<i);
				break;
			}
			if (evt_yes == BTN_btnEvent_get(eBtnAck))
			{
				BTN_btnEvent_consume(eBtnAck);
				SI_threadInfo[i].alarmState = SI_STATE_IDLE;
				SI_alarmIDLE(SI_threadInfo[i].alarmLed, SI_threadInfo[i].globalAlarmLed);
			}
			break;
	}
//	if ((SI_threadInfo[i].adcState == SI_ADC_FAULT) && (SI_threadInfo[i].faultState > SI_STATE_IDLE))
	if ((SI_threadInfo[i].adcState == SI_ADC_FAULT) && (SI_threadInfo[i].alarmState > SI_STATE_IDLE))
	{
//		SI_threadInfo[i].alarmState = SI_STATE_IDLE;
//		SI_alarmIDLE(SI_threadInfo[i].alarmLed, SI_threadInfo[i].globalAlarmLed);
		SOSZ_clearSOSZ_SILoAlm(1<<i);
	}
}

#if TEST_SO_FAULT_SEQ
	static unsigned int 	testTicker = 0;
#endif
void test_so_faultSequence_updateTimer(void)
{
#if TEST_SO_FAULT_SEQ
	testTicker++;
#endif
}

void test_so_faultSequence(void)
{
#if TEST_SO_FAULT_SEQ
	if (testTicker == 0)
	{
		SOSZ_notifySOSZ_SILoAlm(1<<0);
	}
	if (testTicker == 130)
	{
		SOSZ_clearSOSZ_SILoAlm(1<<0);
	}
	if (testTicker == 132)
	{
		SOSZ_notifySOSZ_SILoAlm(1<<0);
	}
#endif
}
#if DEBUG_SERIAL_SI
char msg[10];
char * pMsg = &msg[0];
static unsigned char lastTick=0;
#endif
static unsigned char ticks = 0;
void SI_driveGA(unsigned char me, enum eGA_skipToEvac skipToEvac)
{
	WORD val=0, mask=0, tmp=0;
	val = SOSZ_getSOSZ_SILoAlmTrigger();
	mask = (1<<me);
	tmp = val&mask;
	if (tmp == mask) // alarm is active
	{
		// notify GA
		GA_notifyGA_SIalm(mask, skipToEvac);
	}
	else
	{
		GA_clearGA_SIalm(1<<me);
	}
}
void SI_thread(unsigned char setBreakpoint, enum SI_runMode adcRawMode, enum SI_runMode adcStatusMode)
{
	static unsigned char lastTurn = 0;
	static unsigned int lastOneSecondTick = 0;

//	static enum SI_ADC_STATE SI_1_adcState = SI_ADC_NORMAL, SI_2_adcState = SI_ADC_NORMAL;
//	static enum SI_STATE SI_1_State = SI_STATE_IDLE;
//	unsigned char consumedIndex = 10;
//	#define SI_1_INDEX 0
//	BTN_btnEvent_process();

//	SI_ackBtnLogic();
	unsigned char adcTurn = SIadc_getAdcTurn();

	if (lastTurn != adcTurn)
	{
//		test_testPin2_On();
//		SI_2_adc_counts = 1500;
		int i;
		unsigned char eventOneSecondTick = 0;
		if (lastOneSecondTick != oneSecondTick)
		{
			eventOneSecondTick = 1;
			lastOneSecondTick = oneSecondTick;
		}
		for (i = 0; i < SI_ACTIVE; i++)
		{
			if (i == setBreakpoint)
			{
				__no_operation();
			}
			if (SI_threadInfo[i].pSI->fxn != SI_Fxn_INHIBIT_INPUT) // enum SI_functions
			{
				if (adcRawMode == SI_runMode_norm) // if mode is not norm, you can override the ADC values for testing!!
				{
					SIadc_getReading(i, &SI_threadInfo[i].adcCount);// SI_threadInfo[i].adcCount = SIadc_getReading(i);
				}
				//else // SI_runMode_test

				if (adcStatusMode == SI_runMode_norm) {
					SI_adcToStatus_RangeDataFilt(&SI_threadInfo[i].adcCount, &SI_threadInfo[i], pSI_inputTypeTable[SI_threadInfo[i].pSI->InputType]);
//					SI_adcToStatus_RangeData(&SI_threadInfo[i].adcCount, &SI_threadInfo[i].adcState, pSI_inputTypeTable[SI_threadInfo[i].pSI->InputType]);
				}
				switch (SI_threadInfo[i].pSI->InputType)
				{
					case SI_TYPE1:
					case SI_TYPE2:
					case SI_TYPE3:
					case SI_TYPE4:
					{
//						if (adcStatusMode == SI_runMode_norm) {
//							SI_adcToStatus_type4(&SI_threadInfo[i].adcCount, &SI_threadInfo[i].adcState);
////							SI_adcToStatus_RangeData(&SI_threadInfo[i].adcCount, &tempState, ppSI_inputTypeTable[SI_threadInfo[i].pSI->InputType]);
//						}
						SI_almShortingType_SM(i, &btnEvents, eventOneSecondTick);
					}
					break;
					case SI_TYPE5:
					case SI_TYPE6:
					case SI_TYPE7:
					case SI_TYPE8:
					case SI_TYPE9:
					{
//						if (adcStatusMode == SI_runMode_norm){
//							SI_adcToStatus_RangeData(&SI_threadInfo[i].adcCount, &tempState, &SI_inputType_9[0]);
//						}
						SI_NS_SM(i, &btnEvents, eventOneSecondTick);
					}
					break;
				}
//				if (SI_threadInfo[i].adcState != tempState)
//				{
//					__no_operation();
//				}
/*				if (SI_threadInfo[i].pSI->InputType == SI_TYPE4)
				{ // enum SI_type
					SI_adcToStatus_type4(&SI_threadInfo[i].adcCount, SI_threadInfo[i].alarmLed, SI_threadInfo[i].faultLed, &SI_threadInfo[i].adcState);
					SI_almShortingType_SM(i, &btnEvents, eventOneSecondTick);
				}
				else if (SI_threadInfo[i].pSI->InputType == SI_TYPE6)
				{
					SI_adcToStatus_type6(&SI_threadInfo[i].adcCount, SI_threadInfo[i].alarmLed, SI_threadInfo[i].faultLed, &SI_threadInfo[i].adcState);
					SI_NS_SM(i, &btnEvents, eventOneSecondTick);
				}*/
				if (SI_threadInfo[i].inReset == 1)
				{
					SI_threadInfo[i].faultState = SI_STATE_IDLE;
					SI_faultIDLE(SI_threadInfo[i].faultLed, SI_threadInfo[i].globalFaultLed);
				}
				else
				{
					SI_flt_SM(i);
				}

				if (SI_threadInfo[i].pSI->fxn == SI_Fxn_SUPERVISORY)
				{
					__no_operation();
				}
//				WORD val=0, mask=0, tmp=0;
				if (SI_threadInfo[i].pSI->fxn == SI_Fxn_ALARM_NORMAL_GA)
				{
					SI_driveGA(i, DO_NOT_SKIP_EVAC);
//					val = SOSZ_getSOSZ_SILoAlmTrigger();
//					mask = (1<<i);
//					tmp = val&mask;
//					if (tmp == mask) // alarm is active
//					{
//						// notify GA
//						GA_notifyGA_SIalm(mask, DO_NOT_SKIP_EVAC);
//					}
//					else
//					{
//						GA_clearGA_SIalm(1<<i);
//					}
				}
				if (SI_threadInfo[i].pSI->fxn == SI_Fxn_ALARM_SKIP_TO_EVAC)
				{
					SI_driveGA(i, SKIP_EVAC);
//					val = SOSZ_getSOSZ_SILoAlmTrigger();
//					mask = (1<<i);
//					tmp = val&mask;
//					if (tmp == mask) // alarm is active
//					{
//						// notify GA
//						GA_notifyGA_SIalm(mask, SKIP_EVAC);
//					}
//					else
//					{
//						GA_clearGA_SIalm(1<<i);
//					}
				}
#if DEBUG_SERIAL_SI
				if ((lastTick != ticks)&&(Test_Serial_getDebugStatus() == DEBUG_ENABLED))
				{
//					unsigned char si = 0;
		//			char null [1] = {"\n"};

					msg[0] = (SI_threadInfo[i].adcCount)>>8;
					msg[0] &= 0xF;
					msg[1] = (SI_threadInfo[i].adcCount)&0xFF;

					msg[2] = SI_threadInfo[i].adcState;
					msg[3] = SI_threadInfo[i].alarmState;
					msg[4] = SI_threadInfo[i].alarmLed;
		//			extern unsigned char ticksADC;
					msg[5] = ticks;

		//			msg[2] = null[0];
		//			msg[3] = null[0];
					//	*(pMsg+6) = "\n";
					enum DebugCmd cmd = DebugCmd_SI_1;
					cmd += (enum DebugCmd)i;
					Test_Serial_sendCmdAndData(cmd, (unsigned char *)msg, 6);
					if (i == 7)
					{
						lastTick = ticks;
//						SI_TestADport_toggle();
					}
				}
#endif
		//		SI_1_adc_counts = 3801;
		//		SI_adcToStatus_type4(&SI_1_adc_counts, LED_SI_3_Alm, LED_SI_3_Flt);
			}
		}
//		Fault_btnAck();
		BTN_btnEvent_clearAckReset();
		lastTurn = adcTurn;
//		test_testPin2_Off();
	}
//	if (event_ACK())
//	if(	event_btn_debounce(&ACK))
//	test_testPin_On();
//	SI_buzzerLogic();
	SI_globalLedLogic();
	LED_resourceArray_processLED();
	REL_resourceArray_processRELAY();

	test_so_faultSequence();

	//	BTN_btnEvent_clearAckReset();
//	test_testPin2_Off();
}


//static unsigned char atomicTimer = 0;
void SI_incrOneSecTick(void)
{
	oneSecondTick++;
}
void SI_atomicTimerTestLedTimer(void)
{
	if (--ticksLed==0)
	{
		ticksLed = TICKS_LED;
		LED_updateTimer();
//		LED_thread();
//		LED_buzzerLogic();
	}
}
void Time_threadOneSec(void)
{
#if 1
	if(evt_yes == BTN_btnEvent_get(eBtnWarning))
	{
		BTN_btnEvent_consume(eBtnWarning);
		Test_Serial_toggleDebugStatus();
	}
///	ticksLed = 1;
#endif
#if 1
	SI_incrOneSecTick();
#endif
#if 1
	GA_thread();
#endif
#if 1
	FWS_thread();
#endif
//				SOSZ_notifySOSZ_SILoAlm(1<<0);
#if 1
	SOSZ_thread(MODE_NORMAL);
#endif
	test_so_faultSequence_updateTimer();
#if 1
	if (lockOutTimer != 0)
	{
		lockOutTimer--;
	}
	else if(evt_yes == BTN_btnEvent_get(eBtnLampTest))
	{
		BTN_btnEvent_consume(eBtnLampTest);
		LED_setMode(MODE_LAMP_TEST);
		mode = MODE_LAMP_TEST;
		LED_setRateRange(LED_SI_1_Alm, LED_ALARMS, RATE_SLOW);
		LED_resourceArray_requestRateRange(LED_GLOBAL_BEGIN, LED_GLOBAL_END, LED_WARNING, RATE_SLOW);
		lockOutTimer = TICKS_LOCKOUT;
	}
	else if(evt_yes == BTN_btnEvent_get(eBtnSvcMode))
	{
		init_system();
		BTN_btnEvent_consume(eBtnSvcMode);
		LED_setRate(LED_SERVICE_MODE , RATE_ON);
		mode = MODE_SERVICE;
		LED_setMode(mode);
		REL_resourceArray_requestRelay(Relay_Fault, LED_SERVICE_MODE, Relay_On);
//					LED_resourceArray_requestRate(LED_GLOBAL_TROUBLE, LED_SERVICE_MODE, RATE_ON);
		LED_resourceArray_requestRate(LED_GLOBAL_SERVICE_MODE, LED_SERVICE_MODE, RATE_ON);

		lockOutTimer = TICKS_LOCKOUT;
	}
#endif

}
void SI_atomicTimer(void)
{
//	while (!atomicTimer)
//	{
//		__no_operation(); // want to sleep
		//Enter LPM0, enable interrupts
//	    __bis_SR_register(LPM3_bits + GIE);
//	}
//	else
//	{
//	atomicTimer = 0;
	WDT_A_resetTimer(WDT_A_BASE);

	if (lockOutTimer != 0)
	{
		__no_operation();//lockOutTimer--;
	}
	else if (--ticksBtn==0)
	{
//				test_testPin_On();
		ticks++;
		ticksBtn = TICKS_BTN;
		SI_updateBtnTimer();
//		BTN_btnEvent_process();
//				SI_ackBtnLogic();
//				test_testPin_Off();
	}
/*	if (--ticksLed==0)
	{
//		test_testPin_toggle();
		ticksLed = TICKS_LED;
		LED_updateTimer();
//		LED_thread();
//		LED_buzzerLogic();
//		LED_Buzzer_setRate(RATE_FAST);
//		LED_thread_BuzzerHelper(LED_Buzzer_getRate());
//		test_testPin_toggle();
	}*/
	switch (mode)
	{
		case (MODE_NORMAL):
			LED_setMode(MODE_NORMAL);
			if (--ticksFault==0)
			{
				ticksFault = TICKS_FAULT;
				Fault_updateTimer();
			}
			if (--ticksSOSZ==0)
			{
#if 1
				Time_threadOneSec();
#endif
				ticksSOSZ = TICKS_SOSZ;
			}
			if (--ticksADC==0)
			{
				ticksADC = TICKS_ADC;
				test_testPin2_On();
				SIadc_startADCsampleCycle();
			}
		break;
		case (MODE_LAMP_TEST):
			LED_setRateRange(LED_SI_1_Alm, LED_ALARMS, RATE_SLOW);
			LED_resourceArray_requestRateRange(LED_GLOBAL_BEGIN, LED_GLOBAL_END, LED_WARNING, RATE_SLOW);
			if (--ticksSOSZ==0) {
				ticksSOSZ = TICKS_SOSZ;
///				SI_updateBtnTimer();

				if (lockOutTimer != 0)
				{
					lockOutTimer--;
					break;
				}
				if(evt_yes == BTN_btnEvent_get(eBtnLampTest))
				{
					BTN_btnEvent_consume(eBtnLampTest);
					init_system();
					mode = MODE_NORMAL;
					LED_setMode(mode);
					LED_setRateRange(LED_SI_1_Alm, LED_ALARMS, RATE_OFF);
					LED_resourceArray_requestRateRange(LED_GLOBAL_BEGIN, LED_GLOBAL_END, LED_WARNING, RATE_OFF);
					lockOutTimer = TICKS_LOCKOUT;
					break;
				}

			}
		break;
		case (MODE_SERVICE):
			mode = MODE_SERVICE;
			LED_setMode(mode);
			REL_resourceArray_requestRelay(Relay_Fault, LED_SERVICE_MODE, Relay_On);
//			LED_resourceArray_requestRate(LED_GLOBAL_TROUBLE, LED_SERVICE_MODE, RATE_ON);
			LED_resourceArray_requestRate(LED_GLOBAL_SERVICE_MODE, LED_SERVICE_MODE, RATE_ON);
			if (--ticksFault==0)
			{
				ticksFault = TICKS_FAULT;
				Fault_updateTimer();
			}
			if (--ticksSOSZ==0)
			{
				if(evt_yes == BTN_btnEvent_get(eBtnWarning))
				{
					BTN_btnEvent_consume(eBtnWarning);
					Test_Serial_toggleDebugStatus();
				}
				oneSecondTick++;
				ticksSOSZ = TICKS_SOSZ;
				GA_thread();
				FWS_thread();
				SOSZ_thread(MODE_NORMAL);

				if (lockOutTimer != 0)
				{
					lockOutTimer--;
				}
				else if(evt_yes == BTN_btnEvent_get(eBtnLampTest))
				{
					BTN_btnEvent_consume(eBtnLampTest);
					mode = MODE_LAMP_TEST;
					LED_setMode(mode);
					LED_setRateRange(LED_SI_1_Alm, LED_ALARMS, RATE_SLOW);
					LED_resourceArray_requestRateRange(LED_GLOBAL_BEGIN, LED_GLOBAL_END, LED_WARNING, RATE_SLOW);
					lockOutTimer = TICKS_LOCKOUT;
				}
				else if(evt_yes == BTN_btnEvent_get(eBtnSvcMode))
				{
					BTN_btnEvent_consume(eBtnSvcMode);
					init_system();
					mode = MODE_NORMAL;
					LED_setMode(mode);
					LED_setRate(LED_SERVICE_MODE , RATE_OFF);
					REL_resourceArray_requestRelay(Relay_Fault, LED_SERVICE_MODE, Relay_Off);
//					LED_resourceArray_requestRate(LED_GLOBAL_TROUBLE, LED_SERVICE_MODE, RATE_OFF);
					LED_resourceArray_requestRate(LED_GLOBAL_SERVICE_MODE, LED_SERVICE_MODE, RATE_OFF);
					lockOutTimer = TICKS_LOCKOUT;
				}
			}
			if (--ticksADC==0)
			{
				ticksADC = TICKS_ADC;
				test_testPin2_On();
				SIadc_startADCsampleCycle();
			}
		break;

	}

//	}
}

#pragma vector=TIMER1_A0_VECTOR
__interrupt void timer_UI_isr(void)
{  /* I think this is a 25 ms timer */

//	fan_stuff();
//	hoist_debounce_discInputs();
//	hoist_process_signals_and_create_events();
//	uart_tick_1ms();
//	fan_and_hoist_SM();

//	atomicTimer = 1;
//	test_testPin_On();
//	test_testPin_toggle();
	WDT_A_resetTimer(WDT_A_BASE);
//	if (Serial_serialOperation)
//		__no_operation();
//	else
	{
		SI_atomicTimerTestLedTimer();
	//	LED_Buzzer_setRate(RATE_FAST);
		LED_thread_BuzzerHelper(LED_Buzzer_getRate());
	#if 1
		SI_atomicTimer();
	#endif
	//	test_testPin_Off();
	//	LED_thread();

	//	turn++;// = (turn+1)%2;
	}
	// Clear interrupt flag
	TA1CCTL0 &= ~CCIFG;
	__bis_SR_register(GIE);
	WDT_A_start(WDT_A_BASE);
//	__bis_SR_register(LPM3_bits + GIE);		// Enter LPM3
}

